#include"mystdio.h"
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>


MyFILE* my_fopen(const char* filename, const char* mode)
{
    int fd = -1;
    if(strcmp(mode, "w") == 0)
    {
        fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, UMASK);
    }
    else if(strcmp(mode, "r") == 0)
    {
        fd = open(filename, O_RDONLY);
    }
    else if(strcmp(mode, "a") == 0)
    {
        fd = open(filename, O_CREAT | O_WRONLY | O_APPEND, UMASK);
    }
    else if(strcmp(mode, "r+") == 0)
    {
        fd = open(filename, O_CREAT | O_RDWR | O_APPEND, UMASK);
    }
    else
    {

    }
    if(fd < 0)
    {
        return NULL;
    }
    MyFILE* pf = (MyFILE*)malloc(sizeof(MyFILE));
    if(!pf)
    {
        return NULL;
    }
    pf->fileno = fd;
    pf->flag = FLUSH_LINE;
    pf->curr = 0;
    pf->cap = SIZE;
    pf->outbuffer[0] = 0;

    return pf;
}

static void my_fflush_code(MyFILE* pf, int flag)
{
    if(pf->curr <= 0)
    {
        return;
    }
    if(flag == FORCE)
    {
        write(pf->fileno, pf->outbuffer, pf->curr);
        pf->curr = 0;
    }
    if((pf->flag == FLUSH_LINE) && (pf->outbuffer[pf->curr - 1] == '\n'))
    {
        write(pf->fileno, pf->outbuffer, pf->curr);
        pf->curr = 0;
    }
    else if((pf->flag == FLUSH_FULL) && (pf->curr == pf->cap))
    {
        write(pf->fileno, pf->outbuffer, pf->curr);
        pf->curr = 0;
    }
}

int my_fwrite(const char* s, int size, MyFILE* pf)
{
    memcpy(pf->outbuffer + pf->curr, s, size);
    pf->curr += size;
    my_fflush_code(pf, NORMAL);
    return size;
}

void my_fflush(MyFILE* pf)
{
    my_fflush_code(pf, FORCE);
}

void my_fclose(MyFILE* pf)
{
    if(pf->fileno > 0)
    {
        my_fflush(pf);
        fsync(pf->fileno);
        close(pf->fileno);
        free(pf);
    }
}
